#pragma once

#include <bondlib/BondMarketStream.h>
#include <qbprotocol/include/SSQBModel.h>

#include <QFrame>
#include <QList>
#include <QTimer>
#include <map>
#include <vector>

#include "../Filter/FilterInterface.h"
#include "BestQuoteDefines.h"

enum tipsMenu {
  BondDetial,
  QuotationWindow,
  MarginWindow,
  BondSimilar,
  TrialCalculatin,
  HoldCalculatin,
  CopyBondShortName,
  CopyPrice,
  AddDefaultFollow,
  AddFollow,
  SetBondReminder
};

class BestQuoteDlg;
class SVirtualTable;
class BestQuoteModel;
class STabCtrl;
class SImageButton;
class DefaultTableModel;
class STableColumnSet;
class CBrokerUnit;
class QMenu;

class BestQuoteTable : public QFrame {
  Q_OBJECT
 public:
  BestQuoteTable(BestQuoteDlg* parent);
  ~BestQuoteTable();

  void ReloadData();
  BestQuoteModel* currentModel();
  BestQuoteModel* lastModel();

 protected:
  void resizeEvent(QResizeEvent* event) override;
  void sortHeader(int col, bool desc, bool reset = false);

 signals:
  void brokerChanged(int tabIndex);

 protected slots:
  void onFilterChange();
  void onBestPriceReqArrivedAll();
  void onBestPriceArrivedAll(QList<xQBBestPriceUnit_c>);
  void onHeaderSort(int col);
  void onBestPriceRowClicked(const QModelIndex& index);
  void onBestPriceRowDblClicked(const QModelIndex& index);
  void onMixedBestPriceReqArrived();
  void onMixedBestPricePush(QList<xQBMixedBestQuoteUnit_c> lstData);

  void onTableSet();
  void onContextMenu(QPoint pos);
  void onMenuClick(tipsMenu index);

 private:
  void setupUi();
  void initTable();
  void updateTable(bool reset, int selRow = -1, int selBondIndex = -1);
  void updateSpecialListWidth();
  void onBrokerSelChanged();

  bool getCurrentCondition(FilterCondition* filter);
  void getBondList(FilterCondition* pFC);
  void initUi();
  void OpenContactWindows(int bondIndex, int brokerId);
  void refreshSpecialLabel(int index, int bondIndex, QString& specialLabel);
  int getSortKey(int nDefCol);
  bool isSelectedBond();
  void lockList(bool bLock);

  void initMixedBroker(const CBrokerUnit& stUnit);
  void onCheckInMixedPriceTab();
  void onCheckOutMixedPriceTab(bool force);
  void getMixedBondInfoList(FilterCondition* pFC);
  bool isMixedBPTab();
  bool updateMixedBestPriceList(const QList<xQBMixedBestQuoteUnit_c>& lstData,
                                bool bCheck);
  bool isMixedBPPushNeedRefresh(const QList<xQBMixedBestQuoteUnit_c>& lstData);
  bool updateExpandedBond(xQBBestPriceListAck_c* pAck);
  bool expandBond(const BrokerKey& brokerKey);
  std::string getContributorId(const FilterCondition& stFC);

  char* getTakenPriceStr(int index, const CBrokerKeyVector& brokerKeys,
                         int& prcType, QString& szTips);
  char* getTakenPriceStr(int index, const CBrokerKeyVector& brokerKeys,
                         const CBondInfo& bi);

  void StartABTimer();
  void StopABTimer();
  void onABTimer();

 private:
  typedef struct tagLabel {
    QString id;     // ��ǩid
    QString label;  // ��ǩ��
    QString tips;   // ��ǩtips
    QColor color;   // ��ǩ��ɫ
    int order;      // ��ǩչʾ˳��
    bool operator<(const tagLabel& r) const { return order < r.order; }
  } bondSpecialLabel;

  BestQuoteDlg* m_pParent = nullptr;
  SVirtualTable* m_quoteTable = nullptr;
  STabCtrl* m_brokerTab = nullptr;
  SImageButton* m_btnSetting = nullptr;
  DefaultTableModel* m_model = nullptr;
  STableColumnSet* m_tableSet = nullptr;
  std::map<int, BestQuoteModel*> m_quoteModels;
  std::vector<EPriceColType> m_cols;
  std::vector<MarketStreamInfo> m_takens;
  bool m_locked = false;
  bool m_bBestPriceUpdated = false;
  bool m_bFirstReqABBond = true;
  QMenu* m_tipMenu = nullptr;
  CBondInfo* m_index = nullptr;
  BrokerKey* m_broker = nullptr;
  BrokerKey m_selected_key;  // ѡ�е�ծȯkey
  QTimer* m_abTimer = nullptr;
  QString m_copyData;
  QString m_selRowKey;
};